import axios, {
    AxiosError,
    AxiosRequestConfig,
    AxiosResponse,
    InternalAxiosRequestConfig,
} from 'axios';
import { ElMessage } from 'element-plus';
import Http from '../types/global/request.d';
import { useStore } from '@/store/user';
import Cookies from 'js-cookie';
// create an axios instance
const service = axios.create({
    baseURL: import.meta.env.VITE_APP_API,
    headers: {
        'Content-Type': 'application/json',
    },
});

// 请求拦截
service.interceptors.request.use(requestInterceptor, (error) => {
    return Promise.reject(error);
});

// 响应拦截
service.interceptors.response.use(interceptors, handlerResponseReject);

/** 响应拦截器
 *  @param {AxiosResponse<any, any>} response 请求响应数据
 */
function interceptors(response: AxiosResponse<any, any>) {
    const data: Http.Response<any> = response.data;

    if (data.code >= 200 && data.code < 300) {
        return data as any;
    }
    errorMessage(data.message);
    return Promise.reject(data);
}

/** 请求拦截器
 *  @param {InternalAxiosRequestConfig<any>} config axios请求实例
 *  @return {InternalAxiosRequestConfig<any>}
 */
function requestInterceptor(config: InternalAxiosRequestConfig<any>) {
    const store = useStore();
    config.headers!['X-Access-Token'] = store.token; // 请求头配置token
    return config;
}

/** HTTP响应错误处理
 *  @param {AxiosError} error 响应错误参数
 *  @return {Promise<AxiosError>}
 */
function handlerResponseReject(error: AxiosError) {
    const status = error.response?.status;

    switch (status) {
        case 401:
            const store = useStore();
            store.userInfo = undefined;
            store.token = undefined;
            Cookies.remove('_token');
            errorMessage('Sorry, login has expired, please login again!');
            break;
        case 403:
            errorMessage('access denied');
            break;
        case 404:
            errorMessage('Resource not found');
            break;
        case 500:
            errorMessage('Server internal error');
            break;
        case 504:
            errorMessage('network timeout');
            break;
        default:
            break;
    }
    return Promise.reject(error);
}
/** 错误信息 */
function errorMessage(msg: string) {
    // 关闭生产环境下的请求错误提示
    // if (import.meta.env.MODE !== 'development') {
    //     return;
    // }
    ElMessage({
        message: msg || '请求错误',
        type: 'error',
        duration: 5 * 1000,
    });
}

function get<T>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig<any>,
): Promise<Http.Response<T>> {
    return service.get(url, {
        ...config,
        params: data,
    });
}

function post<T>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig<any>,
): Promise<Http.Response<T>> {
    return service.post(url, data, config);
}

function put<T>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig<any>,
): Promise<Http.Response<T>> {
    return service.put(url, data, config);
}

function del<T>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig<any>,
): Promise<Http.Response<T>> {
    return service.delete(url, { params: data, ...config });
}

export default { get, post, put, del };
